package com.wisenet.wx.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.alibaba.fastjson.JSONObject;
import com.wisenet.common.WxConst;

public class WeChatApiUtil {
	private static Logger logger = Logger.getLogger(WeChatApiUtil.class);
    
    /**
     * 微信服务器素材上传
     * @param parts
     * @param url
     * @return
     */
	public static JSONObject uploadMedia(Part[] parts, String url) {
        JSONObject jsonResult = new JSONObject();
        
        PostMethod postMethod = new PostMethod(url);
        postMethod.getParams().setContentCharset("UTF-8");
        postMethod.setRequestHeader("Connection", "Keep-Alive");
        postMethod.setRequestHeader("Cache-Control", "no-cache");
        
        // 信任任何类型的证书
//      Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443); 
//      Protocol.registerProtocol("https", myhttps);
        InputStream inputStream = null;
        BufferedReader bufReader = null;
        HttpClient httpClient = new HttpClient();
        try {
        	// 请求参数
        	MultipartRequestEntity entity = new MultipartRequestEntity(parts, postMethod.getParams());
            postMethod.setRequestEntity(entity);
            // 发送请求
            int status = httpClient.executeMethod(postMethod);
            if (status == HttpStatus.SC_OK) {
            	byte[] bytes = postMethod.getResponseBody();
            	// 出现乱码，无解
            	/*StringBuffer strBuffer = new StringBuffer();
                inputStream = postMethod.getResponseBodyAsStream();
                bufReader = new BufferedReader(new InputStreamReader(inputStream));
                String str = "";
                while ((str = bufReader.readLine()) != null) {
                	strBuffer.append(str);  
                }*/
                jsonResult = JSONObject.parseObject(new String(bytes, "UTF-8"));
            } else {
            	logger.info("upload Media failure status is: " + status);
            }
        } catch (Exception exception) {
        	logger.info("upload Media Exception: " + exception);
        } finally {
        	try {
				if (bufReader != null) bufReader.close();
				if (inputStream != null) inputStream.close();
				postMethod.releaseConnection();
			} catch (IOException e) {}
        }
        return jsonResult;
    }
	
	/**
	 * 小程序图片检测
	 * @param inputStream
	 * @param accessToken
	 * @return
	 */
	public static JSONObject checkImage(InputStream inputStream, String accessToken) {
		JSONObject jsonResult = new JSONObject();

		CloseableHttpResponse response = null;
		HttpPost httpPost = new HttpPost(WxConst.IMG_CHECK_URL + accessToken);
		httpPost.addHeader("Content-Type", "application/octet-stream");
		CloseableHttpClient httpclient = HttpClients.createDefault();
		try {
			byte[] bytes = new byte[inputStream.available()];
			inputStream.read(bytes);
			
			httpPost.setEntity(new ByteArrayEntity(bytes, ContentType.create("image/jpg")));

			response = httpclient.execute(httpPost);
			
			String result = EntityUtils.toString(response.getEntity(), "UTF-8");
			jsonResult = JSONObject.parseObject(result);
			
			logger.info("checkImageResult: " + jsonResult);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
        	try {
				if (inputStream != null) inputStream.close();
				httpPost.releaseConnection();
			} catch (IOException e) {}
        }
		return jsonResult;
	}

    /**
     * 多媒体下载接口
     * @comment 不支持视频文件的下载
     * @param fileName  素材存储文件路径
     * @param token     认证token
     * @param mediaId   素材ID（对应上传后获取到的ID）
     * @return 素材文件
     */
    public static File downloadMedia(String fileName, String token, String mediaId) {
        return httpRequestToFile(fileName, token, mediaId);
    }

    /**
     * 以http方式发送请求,并将请求响应内容输出到文件
     * @param fileName
     * @param token
     * @param mediaId
     * @return
     */
    public static File httpRequestToFile(String fileName, String token, String mediaId) {
		if (fileName == null) {
			return null;
		}
        File file = null;
        InputStream inputStream = null;
        FileOutputStream fileOut = null;
        HttpURLConnection connection = null;
        try {
        	connection = getMediaInputStream(token, mediaId);
        	inputStream = connection.getInputStream();
        	
			if (inputStream == null) {
				return null;
			}
			file = new File(fileName);

            // 写入到文件
            fileOut = new FileOutputStream(file);
			if (fileOut != null) {
                int c = inputStream.read();
                while (c != -1) {
                    fileOut.write(c);
                    c = inputStream.read();
                }
            }
        } catch (Exception e) {
        } finally {
            try {
                inputStream.close();
                fileOut.close();
                connection.disconnect();
            } catch (IOException execption) {
            }
        }
        return file;
    }
    
    /**
     * 获取媒体文件流
     * @param token
     * @param mediaId
     * @return
     */
    public static HttpURLConnection getMediaInputStream(String token, String mediaId) {
    	HttpURLConnection connection = null;
        
        String path = String.format(WxConst.GET_MEDIA_URL, token, mediaId);
        try {
            URL url = new URL(path);
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod("GET");

            return connection;
        } catch (Exception e) {
        	logger.error(e);
        	return null;
        }
    }

}
